package aop.xyz.myapp.account;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;

import aop.xyz.myapp.domain.account.User;

@Aspect
public class ConcurrentOperationExecutor implements Ordered {
	private static final Logger log = LoggerFactory
			.getLogger(ConcurrentOperationExecutor.class);

	public static final String CMNTS_BEFORE = "@Around advice before ";
	public static final String CMNTS_AFTER = "@Around advice after ";
	public static final String CMNTS_EXCEP = "@Around advice exception ";
	public static final String CMNTS_FINAL = "@Around advice finally ";

	@Around("aop.xyz.myapp.account.SystemArchitecture.saveUser() && args(user)")
	public Object doConcurrentOperation(ProceedingJoinPoint pjp, User user) {
		try {
			// Before
			log.debug("Before " + pjp.getSignature());
			user.setComments(user.getComments() + CMNTS_BEFORE);

			Object result = pjp.proceed();

			// After
			log.debug("After " + pjp.getSignature());
			user.setComments(user.getComments() + CMNTS_AFTER);

			return result;
		} catch (Throwable e) {
			// Exception
			log.debug("Exception ocurred in " + pjp.getSignature()
					+ e.getMessage());
			user.setComments(user.getComments() + CMNTS_EXCEP);

		} finally {
			// Final
			log.debug("Final " + pjp.getSignature());
			user.setComments(user.getComments() + CMNTS_FINAL);
		}
		
		return null;
	}

	private int order = 1;

	public int getOrder() {
		return this.order;
	}

	public void setOrder(int order) {
		this.order = order;
	}
}
